package edu.whu.irlab.util.time;

import org.joda.time.LocalDateTime;

import java.sql.Timestamp;
import java.util.Calendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 通过正则表达式和各个日期字段匹配的组来识别表达式中的时间
 * Created by 声伟 on 2014/4/26 0026.
 */
public class PatternStandardizer implements DateStandardizer {
    private String regex;
    private int[] groupNumArr = new int[6];   //分别对应年月日时分秒的组位置，如果为0表示不存在
    private int year = 0;
    private int month = 0;
    private int day = 0;
    private int hour = -1;
    private int minute = -1;
    private int second = -1;


    public PatternStandardizer(String regex, int[] groupNumArr) {
        this.regex = regex;
        this.groupNumArr = groupNumArr;
    }

    @Override
    public Timestamp get(String date) {
        if (date == null || date.trim().equals("")) {
            return null;
        }
        Pattern pt = Pattern.compile(regex);
        Matcher mt = pt.matcher(date);
        if (mt.matches()) {
            if (groupNumArr[0] <= 0) {  //有些网页有可能会省略年份
                year = Calendar.getInstance().get(Calendar.YEAR);   //测试时不可用
            } else {
                year = Integer.parseInt(mt.group(groupNumArr[0]));
            }
            mt.group(groupNumArr[0]);
            mt.group(groupNumArr[1]);
            month = month2Num(mt.group(groupNumArr[1]));
            day = Integer.parseInt(mt.group(groupNumArr[2]));
            if (groupNumArr[3] > 0) {
                final String g = mt.group(groupNumArr[3]);
                if (g != null) {
                    hour = (Integer.parseInt(g));
                }
            }
            if (groupNumArr[4] > 0) {
                String g = mt.group(groupNumArr[4]);
                if (g != null) {
                    minute = (Integer.parseInt(g));
                }
            }
            if (groupNumArr[5] > 0) {
                String g = mt.group(groupNumArr[5]);
                if (g != null) {
                    second = Integer.parseInt(g);
                }
            }
            return standard(year, month, day, hour, minute, second);
        }
        return null;
    }

    /**
     * 标准时间格式是2013-12-02 12:03:23
     *
     * @param year
     * @param month
     * @param day
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    private Timestamp standard(int year, int month, int day, int hour, int minute, int second) {
        if (year <= 0 || month <= 0 || day <= 0) {
            return null;
        }
        LocalDateTime dateTime = new LocalDateTime();
        dateTime = dateTime.year().setCopy(year).monthOfYear().setCopy(month).dayOfMonth().setCopy(day);
        if (hour < 0) {
            return new Timestamp(dateTime.hourOfDay().withMinimumValue().minuteOfHour().withMinimumValue().secondOfMinute().withMinimumValue().millisOfSecond().withMinimumValue().toDate().getTime());
        } else {
            dateTime = dateTime.hourOfDay().setCopy(hour);
        }
        if (minute < 0) {
            return new Timestamp(dateTime.minuteOfHour().withMinimumValue().secondOfMinute().withMinimumValue().millisOfSecond().withMinimumValue().toDate().getTime());
        } else {
            dateTime = dateTime.minuteOfHour().setCopy(minute);
        }

        if (second < 0) {
            return new Timestamp(dateTime.secondOfMinute().withMinimumValue().millisOfSecond().withMinimumValue().toDate().getTime());
        } else {
            return new Timestamp(dateTime.secondOfMinute().setCopy(second).millisOfSecond().withMinimumValue().toDate().getTime());
        }
    }


    //Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
    //如果返回0则表示识别失败
    public int month2Num(String m) {
        if (m.matches("\\d+")) {
            return Integer.parseInt(m);
        }
        if (m.equalsIgnoreCase("Jan")) {
            return 1;
        } else if (m.equalsIgnoreCase("Feb")) {
            return 2;
        } else if (m.equalsIgnoreCase("Mar")) {
            return 3;
        } else if (m.equalsIgnoreCase("Apr")) {
            return 4;
        } else if (m.equalsIgnoreCase("May")) {
            return 5;
        } else if (m.equalsIgnoreCase("Jun")) {
            return 6;
        } else if (m.equalsIgnoreCase("Jul")) {
            return 7;
        } else if (m.equalsIgnoreCase("Aug")) {
            return 8;
        } else if (m.equalsIgnoreCase("Sep")) {
            return 9;
        } else if (m.equalsIgnoreCase("Oct")) {
            return 10;
        } else if (m.equalsIgnoreCase("Nov")) {
            return 11;
        } else if (m.equalsIgnoreCase("Dec")) {
            return 12;
        }
        return 0;
    }
}
